/*
 * guifrontend.java
 *
 * Created on March 7, 2009, 2:43 PM
 */

package forensicsGUI;

import foremost.foremostInstance;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import java.io.File;
import java.util.*;
import javax.swing.JList;
import javax.swing.DefaultListModel;
import javax.swing.table.*;
import java.io.*;
import java.awt.*;
import java.util.*;
import java.text.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.util.Timer;
import javax.swing.text.StyledEditorKit.ForegroundAction;
/**
 *
 * @author  marc
 */
public class guifrontend extends javax.swing.JFrame {

    /** Creates new form guifrontend */
    private final JFileChooser fc = new JFileChooser();
    private Vector<String> imageFileList = new Vector<String>();
    private Vector<foremostInstance> executions = new Vector<foremostInstance>();
    private ProgramState currentState = new ProgramState();
    private IntermittentSave stateSaver = new IntermittentSave();
    private UpdateGuiTask execTableupdater = new UpdateGuiTask();
    DefaultListModel listModel = new DefaultListModel();
    DefaultListModel execListModel = new DefaultListModel();
    private Timer timer = null;
    private Timer paneTimer = null;
    private boolean parallel = false;
     
    

    public guifrontend(){
        initComponents();
        //tabbedPane.setSize( getSize());
        centerScreen();
        
        /**/
        try
        {
            Dimension dim = tabbedPane.getSize();
            dim.setSize(tabbedPane.getSize().getWidth()+8, tabbedPane.getSize().getHeight()+8);
            setSize(  dim);
//            update(getGraphics());
            tabbedPane.updateUI();
        }
        catch(Exception e)
        {
            //e.printStackTrace();
        }
        //imagelist = new JList( imageFileList );
        imagelist.setModel(listModel);
        imagelist.updateUI();
        fc.setMultiSelectionEnabled(true);    
         
        //executionTable.setModel(execListModel);
        //executionTable.setCellRenderer(new MyCellRenderer());
        
        // Read from disk using FileInputStream
        
        loadState();
        execTableupdater.setExecutionTable(executionTable);
        
        stateSaver.setCaseDetailsField(caseDetails);
        stateSaver.setCaseField(caseNumber);
        stateSaver.setImageList(imageFileList);
        stateSaver.setStateManager(currentState);
        stateSaver.setInvestigatorField(investName);
        stateSaver.setAuditOnlyField(auditOnly);
        stateSaver.setQuickModeField(quickMode);
        stateSaver.setPartialHeadersField(partialHeaders);
        stateSaver.setExecutable(execName);
        stateSaver.setInstallDir(installDir);
        stateSaver.setMaxMem(memsize);
        stateSaver.setParallel(parallel);
        stateSaver.setOutputDir(outputDir);
        
        
        
//        timer = new Timer();
  //      timer.scheduleAtFixedRate(stateSaver,10000,30 * 1000); // every 30 sec
        paneTimer = new Timer();
        paneTimer.scheduleAtFixedRate(execTableupdater,1000,2 * 1000); // every 30 sec
        
        addWindowListener(new FrameListener(stateSaver));
        guifrontend.calcColumnWidths(finishedTable);
        guifrontend.calcColumnWidths(executionTable);
    
        
    }
    
    
   
    public void loadState()
    {
        try
        {
            FileInputStream f_in = new FileInputStream("foremostgui.dat");

                // Read object using ObjectInputStream
                ObjectInputStream obj_in = 
                        new ObjectInputStream (f_in);

                // Read an object
                Object obj = obj_in.readObject();

                if (obj instanceof ProgramState)
                {
                        // Cast object to a Vector
                        currentState = (ProgramState) obj;

                        caseDetails.setText( currentState.getCaseDetails() );
                        
                        caseNumber.setText( currentState.getCaseNumber() );
                        
                        investName.setText( currentState.getInvestigatorName() );
                        
                        execName.setText( currentState.getExecutable() );
                        
                        installDir.setText( currentState.getInstallDir() );
                        
                        outputDir.setText( currentState.getOutputDir() );
                        
                        memsize.setText( currentState.getMaxMem() );
                        
                        parallel = currentState.getParallel();
                        quickMode.setSelected(currentState.getQuickMode());
                        auditOnly.setSelected(currentState.getAuditOnly());
                        partialHeaders.setSelected(currentState.getPartialHeaders());
                        
                        Vector<AuditedInstances> auditedInstances = currentState.getExecutedInstances();
                        if (auditedInstances!= null)
                        {
                            for (int i=0; i < auditedInstances.size(); i++)
                            {
                                finishedTable.getModel().setValueAt(auditedInstances.get(i),1,1);
                            }
                        }
                        /*
                         * 
                         * if (reference != null)
                reference.getModel().setValueAt(newInstance,1,1);*/
                        
                        if (parallel == false)
                        {
                            
                            disableParallel();
                        }
                        else
                        {
                            
                            enableParallel();
                        }
                        
                        if (installDir.getText().length() == 0)
                            installDir.setText( System.getProperty("user.dir") );
                        if (execName.getText().length() == 0)
                            execName.setText( "foremost" );
                        if (outputDir.getText().length() == 0)
                            outputDir.setText( System.getProperty("user.dir") );
                        
                        Vector< String > list = currentState.getImageList();
                        if (list != null)
                        {
                            imageFileList = list;
                            for (int i=0; i < list.size(); i++)
                            {
                                listModel.addElement(list.get(i));
                            }
                        }
                }
        }
        catch(Exception e)
        {
            installDir.setText( System.getProperty("user.dir") );
            execName.setText( "foremost" );
            outputDir.setText( System.getProperty("user.dir") );
        }
        //guifrontend.calcColumnWidths(finishedTable);
        
    }
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        buttonGroup1 = new javax.swing.ButtonGroup();
        tabbedPane = new javax.swing.JTabbedPane();
        jPanel2 = new javax.swing.JPanel();
        jLabel7 = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        imagelist = new javax.swing.JList();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        caseDetails = new javax.swing.JTextArea();
        caseNumber = new javax.swing.JTextField();
        investName = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel1 = new javax.swing.JLabel();
        jButton3 = new javax.swing.JButton();
        advancedPane = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        memsize = new javax.swing.JTextField();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        installDir = new javax.swing.JTextField();
        jButton4 = new javax.swing.JButton();
        jLabel12 = new javax.swing.JLabel();
        execName = new javax.swing.JTextField();
        jLabel13 = new javax.swing.JLabel();
        outputDir = new javax.swing.JTextField();
        jButton5 = new javax.swing.JButton();
        auditOnly = new javax.swing.JCheckBox();
        partialHeaders = new javax.swing.JCheckBox();
        quickMode = new javax.swing.JCheckBox();
        jPanel3 = new javax.swing.JPanel();
        jLabel9 = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        jLabel11 = new javax.swing.JLabel();
        jScrollPane3 = new javax.swing.JScrollPane();
        executionTable = new javax.swing.JTable();
        jPanel1 = new javax.swing.JPanel();
        jLabel14 = new javax.swing.JLabel();
        jLabel15 = new javax.swing.JLabel();
        jScrollPane4 = new javax.swing.JScrollPane();
        finishedTable = new javax.swing.JTable();
        jSplitPane1 = new javax.swing.JSplitPane();
        jPanel4 = new javax.swing.JPanel();
        jPanel5 = new javax.swing.JPanel();
        jLabel16 = new javax.swing.JLabel();
        jMenuBar5 = new javax.swing.JMenuBar();
        jMenu9 = new javax.swing.JMenu();
        jMenuItem2 = new javax.swing.JMenuItem();
        jMenu10 = new javax.swing.JMenu();
        jMenuItem1 = new javax.swing.JMenuItem();

        setTitle("Foremost Frontend");
        setBounds(new java.awt.Rectangle(0, 0, 0, 0));
        setLocationByPlatform(true);
        setResizable(false);

        tabbedPane.setTabLayoutPolicy(javax.swing.JTabbedPane.SCROLL_TAB_LAYOUT);
        tabbedPane.setTabPlacement(javax.swing.JTabbedPane.LEFT);
        tabbedPane.setMinimumSize(getPreferredSize());

        jLabel7.setText("Image file(s) to analyze");

        imagelist.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        jScrollPane2.setViewportView(imagelist);

        jButton1.setText("Browse");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jButton2.setText("Begin Analysis");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        caseDetails.setColumns(20);
        caseDetails.setRows(5);
        jScrollPane1.setViewportView(caseDetails);

        caseNumber.setHorizontalAlignment(javax.swing.JTextField.RIGHT);

        investName.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        investName.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                investNameActionPerformed(evt);
            }
        });

        jLabel3.setText("Case Details");

        jLabel2.setText("Case Number");

        jLabel1.setText("Investigator Name");

        jButton3.setText("Remove");
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(jLabel7)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 239, Short.MAX_VALUE))
                    .addComponent(jButton2)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel2)
                            .addComponent(jLabel1)
                            .addComponent(jLabel3))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 270, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel2Layout.createSequentialGroup()
                                .addGap(87, 87, 87)
                                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                    .addComponent(caseNumber)
                                    .addComponent(investName, javax.swing.GroupLayout.PREFERRED_SIZE, 183, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                                        .addComponent(jButton1)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                        .addComponent(jButton3)))))))
                .addGap(156, 156, 156))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel7)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButton3, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel3))
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(investName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(caseNumber, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 169, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(18, 18, 18)
                .addComponent(jButton2)
                .addGap(53, 53, 53))
        );

        tabbedPane.addTab("Foremost Settings", jPanel2);

        advancedPane.setEnabled(false);

        jLabel4.setText("Maximum memory to allocate");

        memsize.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        memsize.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                memsizeActionPerformed(evt);
            }
        });

        jLabel5.setText("MB");

        jLabel6.setText("Foremost install dir");

        installDir.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        installDir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                installDirActionPerformed(evt);
            }
        });

        jButton4.setText("Browse");
        jButton4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton4ActionPerformed(evt);
            }
        });

        jLabel12.setText("Foremost Executable");

        execName.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        execName.setText("foremost");

        jLabel13.setText("Output Directory");

        outputDir.setHorizontalAlignment(javax.swing.JTextField.RIGHT);

        jButton5.setText("Browse");
        jButton5.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton5ActionPerformed(evt);
            }
        });

        auditOnly.setText(" Only write Audit File");

        partialHeaders.setText("Ignore corrupted/partial files");

        quickMode.setText("Enable quick mode");

        javax.swing.GroupLayout advancedPaneLayout = new javax.swing.GroupLayout(advancedPane);
        advancedPane.setLayout(advancedPaneLayout);
        advancedPaneLayout.setHorizontalGroup(
            advancedPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(advancedPaneLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(advancedPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(quickMode)
                    .addComponent(auditOnly)
                    .addGroup(advancedPaneLayout.createSequentialGroup()
                        .addGroup(advancedPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(advancedPaneLayout.createSequentialGroup()
                                .addGroup(advancedPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                    .addGroup(advancedPaneLayout.createSequentialGroup()
                                        .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 218, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 19, Short.MAX_VALUE)
                                        .addComponent(jLabel5))
                                    .addComponent(jLabel13, javax.swing.GroupLayout.Alignment.LEADING))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(advancedPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                    .addComponent(partialHeaders)
                                    .addComponent(memsize, javax.swing.GroupLayout.PREFERRED_SIZE, 111, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(jButton5)
                                    .addComponent(outputDir, javax.swing.GroupLayout.DEFAULT_SIZE, 244, Short.MAX_VALUE)
                                    .addComponent(execName, javax.swing.GroupLayout.DEFAULT_SIZE, 244, Short.MAX_VALUE)
                                    .addComponent(jButton4)))
                            .addGroup(advancedPaneLayout.createSequentialGroup()
                                .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 218, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(installDir, javax.swing.GroupLayout.DEFAULT_SIZE, 283, Short.MAX_VALUE)))
                        .addGap(33, 33, 33))
                    .addComponent(jLabel12, javax.swing.GroupLayout.PREFERRED_SIZE, 218, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );
        advancedPaneLayout.setVerticalGroup(
            advancedPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(advancedPaneLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(advancedPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel6)
                    .addComponent(installDir, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(8, 8, 8)
                .addComponent(jButton4, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(41, 41, 41)
                .addGroup(advancedPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel12)
                    .addComponent(execName, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGroup(advancedPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(advancedPaneLayout.createSequentialGroup()
                        .addGap(43, 43, 43)
                        .addComponent(jLabel13))
                    .addGroup(advancedPaneLayout.createSequentialGroup()
                        .addGap(32, 32, 32)
                        .addComponent(outputDir, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(26, 26, 26)
                .addComponent(jButton5, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(advancedPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(advancedPaneLayout.createSequentialGroup()
                        .addGap(36, 36, 36)
                        .addComponent(memsize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(advancedPaneLayout.createSequentialGroup()
                        .addGap(40, 40, 40)
                        .addGroup(advancedPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel4)
                            .addComponent(jLabel5))))
                .addGroup(advancedPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(advancedPaneLayout.createSequentialGroup()
                        .addGap(35, 35, 35)
                        .addComponent(auditOnly)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(quickMode))
                    .addGroup(advancedPaneLayout.createSequentialGroup()
                        .addGap(27, 27, 27)
                        .addComponent(partialHeaders)))
                .addContainerGap(203, Short.MAX_VALUE))
        );

        tabbedPane.addTab("Advanced Settings", advancedPane);

        jLabel9.setText("This tab identifies the foremost processes executed during this ");

        jLabel10.setText("session. Double click on a foremost execution to get more details about");

        jLabel11.setText("it, including statistics and audit information.");

        executionTable.setModel(new ExecutionTableModel());
        executionTable.setRowHeight(21);
        executionTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                executionTableMouseClicked(evt);
            }
        });
        jScrollPane3.setViewportView(executionTable);

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(jLabel11)
                            .addComponent(jLabel10, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(jLabel9)))
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addGap(22, 22, 22)
                        .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 436, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(87, Short.MAX_VALUE))
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel9)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel10)
                .addGap(12, 12, 12)
                .addComponent(jLabel11)
                .addGap(18, 18, 18)
                .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 350, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(155, Short.MAX_VALUE))
        );

        tabbedPane.addTab("Running Sessions", jPanel3);

        jLabel14.setText("This tab identifies Foremost sessions which have completed  ");

        jLabel15.setText("Double click on a session to view its audit information");

        finishedTable.setModel(new PreviousExecutionTableModel());
        finishedTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_LAST_COLUMN);
        finishedTable.setRowHeight(21);
        finishedTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                finishedTableMousePressed(evt);
            }
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                finishedTableMouseClicked(evt);
            }
        });
        jScrollPane4.setViewportView(finishedTable);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel14)
                            .addComponent(jLabel15)))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(23, 23, 23)
                        .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 433, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(102, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel14)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel15)
                .addGap(61, 61, 61)
                .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 305, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(184, Short.MAX_VALUE))
        );

        tabbedPane.addTab("Finished Sessions", jPanel1);

        javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout.setHorizontalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 100, Short.MAX_VALUE)
        );
        jPanel4Layout.setVerticalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 598, Short.MAX_VALUE)
        );

        jSplitPane1.setLeftComponent(jPanel4);

        javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5);
        jPanel5.setLayout(jPanel5Layout);
        jPanel5Layout.setHorizontalGroup(
            jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 452, Short.MAX_VALUE)
        );
        jPanel5Layout.setVerticalGroup(
            jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 598, Short.MAX_VALUE)
        );

        jSplitPane1.setRightComponent(jPanel5);

        tabbedPane.addTab("tab5", jSplitPane1);

        jLabel16.setText("This tab identifies Foremost sessions which have completed execution ");

        jMenu9.setText("File");

        jMenuItem2.setText("Exit");
        jMenuItem2.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                jMenuItem1MousePressed(evt);
            }
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                jMenuItem1MouseReleased(evt);
            }
        });
        jMenu9.add(jMenuItem2);

        jMenuBar5.add(jMenu9);

        jMenu10.setText("Options");

        jMenuItem1.setText("Clear Finished Sessions");
        jMenuItem1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                jMenuItem1MouseReleased1(evt);
            }
        });
        jMenu10.add(jMenuItem1);

        jMenuBar5.add(jMenu10);

        setJMenuBar(jMenuBar5);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(tabbedPane, javax.swing.GroupLayout.PREFERRED_SIZE, 690, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(tabbedPane, javax.swing.GroupLayout.PREFERRED_SIZE, 602, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

private void addExecution(foremostInstance instance)
{
      executions.add(instance);
      //currentState.addExecution(instance);
      instance.setExecList(imageFileList);
      
      executionTable.getModel().setValueAt(instance,1,1);
    
}

public void enableParallel()
{
    parallel=true;
    stateSaver.setParallel(parallel);
    jLabel4.setVisible(true);
    memsize.setVisible(true);
    jLabel5.setVisible(true);
}
public void disableParallel()
{
    
    parallel=false;
    stateSaver.setParallel(parallel);
    jLabel4.setVisible(false);
    memsize.setVisible(false);
    jLabel5.setVisible(false);
    
}

public void centerScreen() {
  Dimension dim = getToolkit().getScreenSize();
  Rectangle abounds = getBounds();
  setLocation((dim.width - abounds.width) / 2,
      (dim.height - abounds.height) / 2);
  requestFocus();
}


private void jMenuItem1MousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jMenuItem1MousePressed
  
  
    
}//GEN-LAST:event_jMenuItem1MousePressed

private void jMenuItem1MouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jMenuItem1MouseReleased
        try {
            stateSaver.doSave();
            System.exit(0);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(guifrontend.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(guifrontend.class.getName()).log(Level.SEVERE, null, ex);
        }
}//GEN-LAST:event_jMenuItem1MouseReleased

private void jMenuItem1MouseReleased1(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jMenuItem1MouseReleased1
    currentState.removeFinishedSession();
    finishedTable.removeAll();
    ((PreviousExecutionTableModel)finishedTable.getModel()).removeAll();
    
}//GEN-LAST:event_jMenuItem1MouseReleased1

private void finishedTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_finishedTableMouseClicked
    if (evt.getClickCount() == 2) {
        int row = finishedTable.getSelectedRow();
        AuditedInstances instance =currentState.getExecutedInstances().get(row); //currentState.getExecutions().get(row); //.get(row);
        statusFrame newFrame = new statusFrame(parallel);
        newFrame.loadAuditInformation(instance);
        newFrame.showAudit();
    }
}//GEN-LAST:event_finishedTableMouseClicked

private void finishedTableMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_finishedTableMousePressed
    // TODO add your handling code here:
}//GEN-LAST:event_finishedTableMousePressed

private void executionTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_executionTableMouseClicked
    if (evt.getClickCount() == 2) {
        int row = executionTable.getSelectedRow();
        foremostInstance instance = executions.get(row); //currentState.getExecutions().get(row); //.get(row);
        instance.showFrame();
    }
}//GEN-LAST:event_executionTableMouseClicked

private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton5ActionPerformed
    fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    int returnVal = fc.showOpenDialog(null);
    //System.out.println(returnVal + " " + JFileChooser.APPROVE_OPTION);


    if (returnVal == JFileChooser.APPROVE_OPTION) {

        File file = fc.getSelectedFile();
        outputDir.setText( file.getAbsolutePath() );

        //This is where a real application would open the file.

    } else if (returnVal == fc.CANCEL_OPTION) {

    }
}//GEN-LAST:event_jButton5ActionPerformed

private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton4ActionPerformed
    fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    int returnVal = fc.showOpenDialog(null);
    //System.out.println(returnVal + " " + JFileChooser.APPROVE_OPTION);


    if (returnVal == JFileChooser.APPROVE_OPTION) {

        File file = fc.getSelectedFile();
        installDir.setText( file.getAbsolutePath() );
        if (!execName.getText().equals("")) {
            if (foremostInstance.validatePFAPI(installDir.getText()+"/", execName.getText()) == false) {
                disableParallel();
                GuiNotification.displayNotification("The executable you chose is from the original Foremost; The program will still work but some features will be disabled","Foremost Notification",GuiNotification.INFORMATION);
            } else
                enableParallel();
        }
        //This is where a real application would open the file.

    } else if (returnVal == fc.CANCEL_OPTION) {

    }
}//GEN-LAST:event_jButton4ActionPerformed

private void installDirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_installDirActionPerformed
    // TODO add your handling code here:
}//GEN-LAST:event_installDirActionPerformed

private void memsizeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_memsizeActionPerformed
    // TODO add your handling code here:
}//GEN-LAST:event_memsizeActionPerformed

private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
    int selections[]  = imagelist.getSelectedIndices();
    if (selections.length > 0 ) {
        for (int i=selections.length-1; i>= 0; i--) {
            imageFileList.remove(selections[i]);
            listModel.removeElementAt( selections[i]);
        }
    }
}//GEN-LAST:event_jButton3ActionPerformed

private void investNameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_investNameActionPerformed
    // TODO add your handling code here:
}//GEN-LAST:event_investNameActionPerformed

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
    // TODO add your handling code here:
    if (imageFileList.size() == 0)
        GuiNotification.displayNotification("Please add at least one image", "Analysis Error", GuiNotification.ERROR);
    else {
        // not using program state because this can vary per execution
        foremostInstance fi = new foremostInstance(parallel);
        fi.setProgramState( currentState );
        fi.setQuickMode( quickMode.isSelected() );
        fi.setPartialHeaders( partialHeaders.isSelected() );
        fi.setAuditOnly(auditOnly.isSelected() );
        fi.setBackReference( finishedTable ); // such a bad idea
        fi.setRunningReference( executionTable ); // such a bad idea
        fi.setExec(execName.getText());
        fi.setCaseDetails(caseDetails.getText());
        fi.setCaseNumber(caseNumber.getText());
        fi.setInvestigatorName(investName.getText());
        fi.setExecLocation(installDir.getText());
        fi.setOutput(outputDir.getText());
        fi.setMaxMem(memsize.getText());
        addExecution(fi);
        new Thread(fi).start();
        guifrontend.calcColumnWidths(executionTable);
    }
}//GEN-LAST:event_jButton2ActionPerformed

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
    fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
    int returnVal = fc.showOpenDialog(null);
    //System.out.println(returnVal + " " + JFileChooser.APPROVE_OPTION);
    if (returnVal == JFileChooser.APPROVE_OPTION) {

        File [] files = fc.getSelectedFiles();
        File file = fc.getSelectedFile();
        for (int i=0; i < files.length; i++) {
            imageFileList.add( files[i].getPath() );
            listModel.addElement(files[i].getPath());
        }
        //imagelist = new JList( imageFileList );
        imagelist.updateUI();
        //This is where a real application would open the file.

    } else if (returnVal == fc.CANCEL_OPTION) {
        //System.out.println("they canceled");
    }
}//GEN-LAST:event_jButton1ActionPerformed



    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel advancedPane;
    private javax.swing.JCheckBox auditOnly;
    private javax.swing.ButtonGroup buttonGroup1;
    private javax.swing.JTextArea caseDetails;
    private javax.swing.JTextField caseNumber;
    private javax.swing.JTextField execName;
    private javax.swing.JTable executionTable;
    private javax.swing.JTable finishedTable;
    private javax.swing.JList imagelist;
    private javax.swing.JTextField installDir;
    private javax.swing.JTextField investName;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JButton jButton5;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel14;
    private javax.swing.JLabel jLabel15;
    private javax.swing.JLabel jLabel16;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JMenu jMenu10;
    private javax.swing.JMenu jMenu9;
    private javax.swing.JMenuBar jMenuBar5;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItem2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JScrollPane jScrollPane4;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JTextField memsize;
    private javax.swing.JTextField outputDir;
    private javax.swing.JCheckBox partialHeaders;
    private javax.swing.JCheckBox quickMode;
    private javax.swing.JTabbedPane tabbedPane;
    // End of variables declaration//GEN-END:variables

     static class MyCellRenderer extends JPanel implements ListCellRenderer{
        JLabel left, middle, right;
        MyCellRenderer() {
        setLayout(new GridLayout(1, 3));
        left = new JLabel();
        middle = new JLabel();
        right = new JLabel();
        left.setOpaque(true);
        middle.setOpaque(true);
        right.setOpaque(true);
        add(left);
        add(middle);
        add(right);
        }

        public Component getListCellRendererComponent(JList list,Object value,int index,boolean isSelected,boolean cellHasFocus){
         foremostInstance fi = (foremostInstance)value;
        
        left.setText("left");
        middle.setText("right");
        right.setText(fi.toString());
        if(isSelected){
        left.setBackground(list.getSelectionBackground());
        left.setForeground(list.getSelectionForeground());
        middle.setBackground(list.getSelectionBackground());
        middle.setForeground(list.getSelectionForeground());
        right.setBackground(list.getSelectionBackground());
        right.setForeground(list.getSelectionForeground());
        }
        else{
        left.setBackground(list.getBackground());
        left.setForeground(list.getForeground());
        middle.setBackground(list.getBackground());
        middle.setForeground(list.getForeground());
        right.setBackground(list.getBackground());
        right.setForeground(list.getForeground());
        }
        setEnabled(list.isEnabled());
        setFont(list.getFont());
        return this;
        }
        }
    
      public  static void calcColumnWidths(JTable table)
{
    JTableHeader header = table.getTableHeader();

    TableCellRenderer defaultHeaderRenderer = null;

    if (header != null)
        defaultHeaderRenderer = header.getDefaultRenderer();

    TableColumnModel columns = table.getColumnModel();
    TableModel data = table.getModel();

    int margin = columns.getColumnMargin(); // only JDK1.3

    int rowCount = data.getRowCount();

    int totalWidth = 0;

    for (int i = columns.getColumnCount() - 1; i >= 0; --i)
    {
        TableColumn column = columns.getColumn(i);
            
        int columnIndex = column.getModelIndex();
            
        int width = -1; 

        TableCellRenderer h = column.getHeaderRenderer();
          
        if (h == null)
            h = defaultHeaderRenderer;
            
        if (h != null) // Not explicitly impossible
        {
            Component c = h.getTableCellRendererComponent
                   (table, column.getHeaderValue(),
                    false, false, -1, i);
                    
            width = c.getPreferredSize().width;
        }
       
        for (int row = rowCount - 1; row >= 0; --row)
        {
            TableCellRenderer r = table.getCellRenderer(row, i);
                 
            Component c = r.getTableCellRendererComponent
               (table,
                data.getValueAt(row, columnIndex),
                false, false, row, i);
        
                width = Math.max(width, c.getPreferredSize().width);
        }

        if (width >= 0)
            column.setPreferredWidth(width + margin); // <1.3: without margin
        else
            ; // ???
            
        totalWidth += column.getPreferredWidth();
    }

// only <1.3:   totalWidth += columns.getColumnCount() * columns.getColumnMargin();


    /* If you like; This does not make sense for two many columns!
    Dimension size = table.getPreferredScrollableViewportSize();

    size.width = totalWidth;

    table.setPreferredScrollableViewportSize(size);
    */

    // table.sizeColumnsToFit(-1); <1.3; possibly even table.revalidate()

    // if (header != null)
    //     header.repaint(); only makes sense when the header is visible (only <1.3)
    }
}
class FrameListener extends WindowAdapter
{
    private IntermittentSave saver=null;
    FrameListener(IntermittentSave saver)
    {
        this.saver=saver;
    }
   public void windowClosing(WindowEvent e)
  {
        try {
            if (saver != null) {
                saver.doSave();
            }
            System.exit(0);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(FrameListener.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(FrameListener.class.getName()).log(Level.SEVERE, null, ex);
        }
  }
   
   
}
